package com.waypolice.common.utils;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @Description 通过反射获取对象方法
 * @Author wangrang
 * @Date Created in 16:07 2019/3/28
 * @Modified By:
 */
public class ReflectionObjectUtil {

    /**
     * 根据属性，获取get方法
     * @param ob 对象
     * @param name 属性名
     * @return
     * @throws Exception
     */
    public static Object getGetMethod(Object ob , String name)throws Exception {
        Method[] m = ob.getClass().getMethods();
        for (int i = 0; i < m.length; i++) {
            if (("get" + name).toLowerCase().equals(m[i].getName().toLowerCase())) {
                return m[i].invoke(ob);
            }
        }
        return null;
    }

    /**
     * 该方法用于传入某实例对象以及对象方法名、修改值，通过放射调用该对象的某个set方法设置修改值
     * @param beanObj
     * @param value
     */
    public static void setProperty(Object beanObj, Object value){
        try {
            //获得属性
            Field[] fields = beanObj.getClass().getDeclaredFields();
            Class clazz = beanObj.getClass();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                Class<?> type = fields[i].getType();
                // 此处应该判断beanObj,property不为null
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), beanObj.getClass());
                Method setMethod = pd.getWriteMethod();
                if (setMethod != null) {
                    System.out.println(beanObj+"的字段是:"+field.getName()+"，参数类型是："+field.getType()+"，set的值是： "+value);
                    //这里注意实体类中set方法中的参数类型，如果不是String类型则进行相对应的转换
                    //invoke是执行set方法
                    setMethod.invoke(beanObj, value);
                    if (type.toString().equals("class java.lang.String")) {
                        //调用实例对象obj的set方法进行对属性的数值
                        setMethod.invoke(beanObj, value.toString());
                    } else if (type.toString().equals("int") || type.toString().equals("class java.lang.Integer")) {
                        setMethod.invoke(beanObj, (Integer) value);
                    } else if (type.toString().equals("class java.util.Date")) {
                        setMethod.invoke(beanObj, DateTimeUtil.strToDateLong(value.toString()));
                    } else if (type.toString().equals("class java.lang.Float")) {
                        setMethod.invoke(beanObj,  Float.parseFloat(value.toString()));

                    } else if (type.toString().equals("class java.lang.Long")) {
                        setMethod.invoke(beanObj,  Long.valueOf(value.toString()));

                    }
                }
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行set方法
     * @param o 实体对象bean
     * @param fieldName  字段名
     * @param value  该字段需要set的值
     */
    public static void invokeSet(Object o, String fieldName, Object value) {
        Method method = getSetMethod(o.getClass(), fieldName);
        try {
            String fields = getFields(o, fieldName);
            if (fields.toString().equals("class java.lang.String")) {
                //调用实例对象obj的set方法进行对属性的数值
                method.invoke(o, new Object[] {value.toString()});
            } else if (fields.toString().equals("int") || fields.toString().equals("class java.lang.Integer")) {
                method.invoke(o, new Object[] {Integer.valueOf(value.toString())});
            } else if (fields.toString().equals("class java.util.Date")) {
               /* method.invoke(o, new Object[] {DateTimeUtil.strToDateLong(value.toString())});*/
                method.invoke(o, new Object[] {DateTimeUtil.strToDate(value.toString())});
            } else if (fields.toString().equals("class java.lang.Float")) {
                method.invoke(o, new Object[] {Float.parseFloat(value.toString())});
            } else if (fields.toString().equals("class java.lang.Long")) {
                method.invoke(o, new Object[] { Long.valueOf(value.toString())} );
            }else {
                method.invoke(o, new Object[] { value });
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * java反射bean的set方法
     * @param objectClass
     * @param fieldName
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Method getSetMethod(Class objectClass, String fieldName) {
        try {
            Class[] parameterTypes = new Class[1];
            Field field = objectClass.getDeclaredField(fieldName);
            parameterTypes[0] = field.getType();
            StringBuffer sb = new StringBuffer();
            sb.append("set");
            sb.append(fieldName.substring(0, 1).toUpperCase());
            sb.append(fieldName.substring(1));
            Method method = objectClass.getMethod(sb.toString(), parameterTypes);
            return method;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 执行get方法
     * @param o     实体对象bean
     * @param fieldName 字段名
     * @return
     */
    public static Object invokeGet(Object o, String fieldName) {
        Method method = getGetMethod(o.getClass(), fieldName);
        try {
            return method.invoke(o, new Object[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * java反射bean的get方法
     * @param objectClass
     * @param fieldName
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Method getGetMethod(Class objectClass, String fieldName) {
        StringBuffer sb = new StringBuffer();
        sb.append("get");
        sb.append(fieldName.substring(0, 1).toUpperCase());
        sb.append(fieldName.substring(1));
        try {
            return objectClass.getMethod(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /** 属性字段名、值、数据类型 */
    public static String getFields(Object object,String fieldName){
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String classType = field.getType().toString();
            String name = field.getName();
            System.out.println("实体对象名："+name+",实体对象数据类型："+classType);
            if(name.equals(fieldName)){
                return classType;
            }
        }
        return "not";
    }


}
